﻿//  --------------------------------
//  Copyright (c) AW Systems, Inc. All rights reserved.
//  This source code is made available under the terms of the Microsoft Public License (Ms-PL)
//  http://www.codeplex.com/SLAM/license
//  ---------------------------------

using System;
using AWS.SLAM.Configuration;
using AWS.SLAM.Data;
using AWS.SLAM.Events;
using AWS.SLAM.Hierarchy.Data;
using AWS.SLAM.Logging;
using Microsoft.SharePoint;

namespace AWS.SLAM.Hierarchy
{
    /// <summary>
    /// HierarchicalContentTypeItemDeleter appropriatley removes an item from the hierarchy of items
    /// managed in SLAM's datasource(s) then deletes the item in SLAM when a List Item 
    /// configured to be managed by SLAM according to its Content Type is deleted in SharePoint.  
    /// 
    /// A Content Type in SharePoint configured to use the HierarchicalContentTypeItemDeleter requires 
    /// that it contain a field of type HierarchyPositionField.
    /// </summary>
    public class HierarchicalContentTypeItemDeleter : ContentTypeItemDeleter
    {
        #region Private State

        /// <summary>
        /// SLAM Data service layer
        /// </summary>
        private IDataServices _dataServices;

        /// <summary>
        /// SLAM Configuration
        /// </summary>
        private IConfigurationManager _configuration;

        /// <summary>
        /// SLAM Logger
        /// </summary>
        private ILogger _logger;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates instance of HierarchicalContentTypeItemDeleter for the given 
        /// DataServices, Configuration, and Logger.
        /// </summary>
        /// <param name="dataServices"></param>
        /// <param name="configuration"></param>
        /// <param name="logger"></param>
        public HierarchicalContentTypeItemDeleter(IDataServices dataServices, IConfigurationManager configuration, ILogger logger)
            : base(dataServices, configuration, logger)
        {
            _dataServices = dataServices;
            _configuration = configuration;
            _logger = logger;
        }

        #endregion

        /// <summary>
        /// Deletes an item from the hierarchy managed by SLAM for the List Item's Content Type and removes
        /// its children if any exist from the hierarchy, without completely deleting each item, then it
        /// deletes the item from SLAM's external datasource.
        /// </summary>
        /// <param name="listItem"></param>
        /// <returns></returns>
        public override bool Delete(SPListItem listItem)
        {
            string typeName = SlamItemContext.TypeName;

            //Open Hierarchy's DataService with the Default ConnectionString and DataSchema.
            //This process assumes the Hierarchy is saved in a SQL Server database and is using
            //a SLAM XML Configuration file.
            DataService dataService = new DataService(_configuration.GetSection<ConnectionStringSection>("ConnectionStrings").Default,
                ((XmlSqlDataMapping)_configuration.DataMapping).GetDataSchema());

            //Check configuration for the presence of a TableName for the listItem's
            //ContentType.  If it is present, use it as the item's typeName instead of the
            //ContentType Name.  Otherwise if it is not present use the ContentType's Name
            string itemTypeName = _configuration.DataMapping.GetTypeAttribute("", typeName, "TableName");
            if (String.IsNullOrEmpty(itemTypeName))
            {
                itemTypeName = typeName;
            }

            //For this type, add the Hierarchy "Left", "Right", and "Hierarchy Level" columns
            //in the SLAM table if they do not exist.
            dataService.AddHierarchyColumns(itemTypeName);

            dataService.DeleteNode(itemTypeName, listItem.UniqueId.ToString());

            dataService.RecalculateHierarchyLevels(itemTypeName);

            //Execute default SLAM Delete process for a configured Content Type
            return base.Delete(listItem);
        }
    }
}
